﻿using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Phone.Maps.Controls;
using Microsoft.Phone.Controls;

namespace RadarGlobal
{
    public static class MapPolygonEx
    {
        
    }
    public static class GeoCoordinateExtensions
    {

        public static GeoCoordinate GetAtDistanceBearing(this GeoCoordinate point,

        double distance, double bearing)
        {

            const double degreesToRadian = Math.PI / 180.0;

            const double radianToDegrees = 180.0 / Math.PI;

            const double earthRadius = 6378137.0;

            var latA = point.Latitude * degreesToRadian;

            var lonA = point.Longitude * degreesToRadian;

            var angularDistance = distance / earthRadius;

            var trueCourse = bearing * degreesToRadian;

            var lat = Math.Asin(

            Math.Sin(latA) * Math.Cos(angularDistance) +

            Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

            var dlon = Math.Atan2(

            Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),

            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

            var lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

            var result = new GeoCoordinate(lat * radianToDegrees, lon * radianToDegrees);

            return result;

        }
        public static IList<GeoCoordinate> GetCirclePoints(this GeoCoordinate center,

            double radius, int nrOfPoints = 50)
        {

            var angle = 360.0 / nrOfPoints;

            var locations = new List<GeoCoordinate>();

            for (var i = 0; i <= nrOfPoints; i++)
            {

                locations.Add(center.GetAtDistanceBearing(radius, angle * i));

            }

            return locations;

        }
        public static GeoCoordinateCollection CreateRectangle(GeoCoordinate topLeft, GeoCoordinate bottomRight)
        {
            var locations = new GeoCoordinateCollection();
            locations.Add(new GeoCoordinate(topLeft.Latitude, topLeft.Longitude));
            locations.Add(new GeoCoordinate(topLeft.Latitude, bottomRight.Longitude));
            locations.Add(new GeoCoordinate(bottomRight.Latitude, bottomRight.Longitude));
            locations.Add(new GeoCoordinate(bottomRight.Latitude, topLeft.Longitude));
            return locations;
        }

        public static bool Contains(this MapPolygon polyPoints, GeoCoordinate point)
        {
            if (polyPoints.Path == null) return false;

            if (polyPoints.Path.Count < 3)
            {
                return false;
            }

            bool inside = false;
            GeoCoordinate p1, p2;

            //iterate each side of the polygon
            GeoCoordinate oldPoint = polyPoints.Path[polyPoints.Path.Count - 1];

            foreach (GeoCoordinate newPoint in polyPoints.Path)
            {
                //order points so p1.lat <= p2.lat;
                if (newPoint.Latitude > oldPoint.Latitude)
                {
                    p1 = oldPoint;
                    p2 = newPoint;
                }
                else
                {
                    p1 = newPoint;
                    p2 = oldPoint;
                }

                //test if the line is crossed and if so invert the inside flag.
                if ((newPoint.Latitude < point.Latitude) == (point.Latitude <= oldPoint.Latitude)
                    && (point.Longitude - p1.Longitude) * (p2.Latitude - p1.Latitude)
                     < (p2.Longitude - p1.Longitude) * (point.Latitude - p1.Latitude))
                {
                    inside = !inside;
                }

                oldPoint = newPoint;
            }

            return inside;
        }
    }
}
